<template>
    <div>
        <div class="content-panel">
            <div class="page-title">基本信息</div>
            <infoCard :fields="fields" :data="cmp" />
        </div>

        <div class="mt-4 config">
            <div class="content-panel">
                <div class="page-title">
                    <span>组件配置</span>
                </div>
                <div>
                    <el-row>
                        <el-col :span="12">
                            <div class="mb-1">组件类型：</div>
                            <el-radio-group
                                v-model="code"
                                class="mb-2"
                                @change="
                                    script = '';
                                    configChanged();
                                "
                            >
                                <el-radio-button value="chart" label="图表组件" />
                                <el-radio-button value="render" label="灵活组件" />
                            </el-radio-group>
                        </el-col>

                        <el-col :span="12">
                            <div class="mb-1">组件样式：</div>
                            <el-link type="primary" icon="edit" @click="editStyle">编辑</el-link>
                        </el-col>
                    </el-row>

                    <div class="mb-1 mt-4 v-center">
                        <span>组件配置：</span>
                        <span v-if="code == 'chart'">
                            <el-link type="primary" v-for="exp in examples" class="mr-2" @click="selectExp(exp)">{{ exp.label }}</el-link>
                        </span>
                        <span v-else>
                            <el-link type="primary" v-for="exp in renderExamples" class="mr-2" @click="selectExp(exp)">{{ exp.label }}</el-link>
                        </span>
                    </div>
                    <monacoEditor v-model="script" language="javascript" height="500px" @change="changed = true" />
                </div>
            </div>

            <div>
                <div class="page-title">预览</div>
                <div>
                    <el-button @click="preview" type="primary" class="mb-2">预览</el-button>
                </div>
                <div class="preview-container">
                    <wrapper :designing="false" :cmp="cmpConfig" class="wrapper" v-if="cmpConfig" :key="key" />
                </div>
            </div>
        </div>

        <div class="buttons text-center mt-2">
            <el-button @click="close" icon="close">关闭</el-button>
            <el-button type="primary" icon="Check" @click="save" :disabled="!changed">保存</el-button>
            <el-button type="success" icon="Checked" @click="publish" :disabled="published">发布</el-button>
        </div>

        <el-dialog v-model="styleVisible" title="组件样式配置">
            <monacoEditor v-model="styleModel" language="json" height="500px" />
            <template #footer>
                <el-button @click="styleVisible = false" icon="close">取消</el-button>
                <el-button type="primary" icon="Check" @click="setStyle">确定</el-button>
            </template>
        </el-dialog>
    </div>
</template>
<script setup>
import infoCard from "@/components/show/info-card.vue";
import monacoEditor from "@/components/monaco-editor.vue";
import Wrapper from "../../../workbench/design/wrapper.vue";
import { onMounted, watchEffect } from "vue";
import { v4 } from "uuid";
import _ from "lodash";
import { examples, renderExamples } from "./examples";

const { cmp } = defineProps({
    cmp: Object,
});
const fields = [
    { label: "组件名称", prop: "name" },
    { label: "组件描述", prop: "remark" },
    {
        label: "组件状态",
        prop: "status",
        converter: (val) => (val == "draft" ? "草稿" : val == "editing" ? "编辑中" : val == "published" ? "已发布" : "已下线"),
    },
    { label: "组件排序", prop: "sort" },
    { label: "添加时间", prop: "createTime" },
];

const script = ref("");
const cmpConfig = ref();
const emits = defineEmits(["change", "close"]);
const key = ref();
const code = ref("chart");
const style = ref({});
const styleVisible = ref(false);
const styleModel = ref("");
// 是否有修改
const changed = ref(false);
const published = ref(false);

onMounted(() => {
    preview();
});

watchEffect(() => {
    let config = cmp.config || {};
    let realCode = config.code || "chart";
    code.value = realCode;
    if (realCode == "chart") {
        script.value = _.get(config, "config.options");
    } else {
        script.value = _.get(config, "config.template");
    }
    style.value = _.get(config, "style", {
        height: "400px",
        width: "100%",
    });
    published.value = cmp.status == "published";
});

function preview() {
    cmpConfig.value = parseConfig();
    key.value = v4();
}

function parseConfig() {
    let config = {};
    config.style = style.value;
    config.code = code.value;
    if (code.value == "chart") {
        _.set(config, "config.options", script.value);
    } else {
        _.set(config, "config.template", script.value);
    }
    return config;
}

function save() {
    app.https.put("/sys/workbench-cmp/update", { id: cmp.id, config: parseConfig() }).then(() => {
        app.success();
        published.value = false;
        changed.value = false;
        emits("change");
    });
}

function editStyle() {
    styleModel.value = JSON.stringify(style.value);
    styleVisible.value = true;
}

function setStyle() {
    style.value = JSON.parse(styleModel.value);
    styleVisible.value = false;
    configChanged;
    preview();
}

function close() {
    emits("close");
}

function configChanged() {
    changed.value = true;
    published.value = false;
}

function selectExp(exp) {
    script.value = exp.value;
    configChanged();
}

function publish() {
    let config = parseConfig();
    app.https.put("/sys/workbench-cmp/update", { id: cmp.id, config, status: "published", publishedConfig: config }).then(() => {
        app.success();
        published.value = true;
        changed.value = false;
        emits("change");
    });
}
</script>

<style lang="scss" scoped>
.config {
    display: grid;
    grid-template-columns: 3fr 2fr;
    gap: 16px;
}

.preview-container {
    height: 600px;
}

.wrapper {
    height: 100%;
}
</style>
